#include "Ball.h"
#include "Shape.h"
#include "Rectangle.h"
#include "Circle.h"

using namespace std;
using namespace gaim;

    Ball::Ball(const Point2& startPos, const std::map<std::string, Image>& images, bool isRect):
                             DynamicSprite(images, "boll", startPos, Vector2(60,60), 1, isRect) {}
    
    
    
    Ball* Ball::getInstance(const Point2& startPos, const std::map<std::string, Image>& images, bool isRect){
        return new Ball(startPos, images, isRect);
    }


    void Ball::update(const std::set<Sprite*, SpritePointerComparator>& sprites, const double dt){
        std::cout << "hi" << endl;
        DynamicSprite::update(sprites, dt);
        std::set<Sprite*> collided = Sprite::checkCollisions(sprites);
  
        if(collided.empty()==false){
            onCollision(collided);
	       	for(std::set<Sprite*>::const_iterator i = collided.begin(); i != collided.end(); ++i){
		      	(*i)->onCollision();
            }
        }
        
        cout << "apa99" << endl;
        
    }

    
    //CURRENTLY WORKING ON - collision detection
    //i need to get the first object from the collided set, and use it for comparisons
    //if the y position plus radius of the ball is less than brick's y plus half height, then bounce bottom
    //if the y position plus radius of ball is greater than, bounce top
    //if x position plus radius of ball is greater than bricks x plus half width, then bounce right
    //else bounce left
    
    //the current position of shapes is in their top left right now - this should be changed to the middle of the shape
    
    //onCollision for ball is going to be called in update if the collision list is not empty
    //inside oncollision we will have the conditions for bounces, but the bounce code is in bounce methods
    void Ball::onCollision(const std::set<Sprite*>& collided){
        
        cout << "apa1" << endl;
        
        Sprite* s = *(collided.begin());
        
        cout << typeid(s).name() << " " << typeid(Ball*).name() << endl;
        
        cout << "apa2" << endl;
        
        const Shape* s1 = s->getShape();
        const double s1height = dynamic_cast<const Rectangle *>(s1)->getHeight();
        const double s1width = dynamic_cast<const Rectangle *>(s1)->getWidth();
       
        cout << "apa3" << endl;
       
        const Shape* s2 = getShape();
        const double s2height = dynamic_cast<const Circle *>(s2)->getRadius();
        const double s2width = dynamic_cast<const Circle *>(s2)->getRadius();
       
        cout << "apa4" << endl;
       
        if(getPos().getY()+s2height > s->getPos().getY()-s1height/2 && getVel().getY()>0){
            hitBottom();
        }
        else if(getPos().getY()-s2height < s->getPos().getY()+s1height/2 && getVel().getY()<0){
            hitTop();
        }
        else if(getPos().getX()+s2width > s->getPos().getX()-s1width/2 && getVel().getX()>0){
            hitRight();
        }
        
        else if(getPos().getX()-s2width < s->getPos().getX()+s1width/2 && getVel().getX()<0){
            hitLeft();
        }
        
        cout << "apa15" << endl;
        
    }
        
/*
        //depending on which side of the ball was hit...
        
        Point2 p = getPos();
        
        if (p.getY()<0){ //if balls origin is higher up that the top of the screen
            [movingObj hitTop];
        }
        p.getY()>
        if (self.frame.origin.y>self.superview.frame.size.height-self.frame.size.height){ //if our origin has gotten higher than the playing fields view minus our own height, we've hit bottom
            [movingObj hitBottom];
            NSLog(@"bottomBALL");
        }
        if (p.getX<0){//if our x coord at origin is more left than the left side of screen
            [movingObj hitLeft];
        }
        if (self.frame.origin.x>self.superview.frame.size.width-self.frame.size.width){//if our origin is more rightwards than the playing fields rightest bound, minus our own width, we're on the right
            [movingObj hitRight];
        }
        
*/


    //hit methods
    
    void Ball::hitRight(){ //if we dont take the absolute versions we can have issues with the direction the ball is travelling
        std::cout << "ballcollide-test-RIGHTSIDE" << std::endl;
        Vector2 v = getVel();
        double x = v.getX();
        double y = v.getY();
        
        double absx = - fabs(x);
        Vector2 vi(absx, y);
        DynamicSprite::setVel(vi);
        std::cout << x << "x and " << y << "y" << "vi" << vi << std::endl;
    }
    
    void Ball::hitLeft(){ 
        std::cout << "ballcollide-test-LEFTSIDE" << std::endl;
        Vector2 v = getVel();
        double x = v.getX();
        double y = v.getY();
        std::cout << x << "x and " << y << "y" << std::endl;
        double absx =  fabs(x);
        Vector2 vi(absx, y);
        DynamicSprite::setVel(vi);
    }
    
    void Ball::hitTop(){ 
        std::cout << "ballcollide-test-TOPSIDE" << std::endl;
        Vector2 v = getVel();
        double x = v.getX();
        double y = v.getY();
        std::cout << x << "x and " << y << "y" << std::endl;
        double absy =  fabs(y);
        Vector2 vi(absy, x);
        DynamicSprite::setVel(vi);
    }
    
    void Ball::hitBottom(){ 
        std::cout << "ballcollide-test-BOTTOMSIDE" << std::endl;
        Vector2 v = getVel();
        double x = v.getX();
        double y = v.getY();
        std::cout << x << "x and " << y << "y" << std::endl;
        double absy = - fabs(y);
        Vector2 vi(absy, x);
        DynamicSprite::setVel(vi);
    }




/*
    void hitRight(){
    Double x = v.getX();
    Double y = v.getY();
    Double absx = - abs(x);
    DynamicSprite::setVel(absx, y);
    //self.xspeed = - abs(self.xspeed);

}

    void hitTop(){
    //self.yspeed = abs (self.yspeed);

}

    void hitBottom(){
   // self.yspeed = -abs(self.yspeed);

   
}
/*
-(void)hitBottom: (float) factoredScaleValue{
   
    self.xspeed = -factoredScaleValue;
    //this is our paddle turned into a -1 to 1 range, then multiplied by the current velocity and modded by 0.9

    self.yspeed = -sqrt(self.velocity * self.velocity - self.xspeed * self.xspeed);
    //the yspeed is calculated using trigonometry and reversed because we're now travelling upwards
   
}
*/

